package ch.quantasy.android.repetitive.implementation;

import java.util.concurrent.TimeUnit;

import android.util.Log;
import ch.quantasy.android.repetitive.definition.RepeaterAction;
import ch.quantasy.android.repetitive.definition.RepeaterStrategy;

/**
 * This {@link RepeaterStrategy} is very usable for repetition-delays between
 * 0.01secs and 1 second. The system is kept running via a
 * {@link Thread#sleep(long)}.
 * 
 * @author quantasy
 * 
 */
public class SleepRepeaterStrategy extends ARepeaterStrategy {
	private final static String TAG = SleepRepeaterStrategy.class
			.getSimpleName();

	private Thread thread;
	private final Runnable updateTimeTask;
	private boolean isRunning;

	/*
	 * (non-Javadoc)
	 * 
	 * @see ch.quantasy.android.repetitive.service.RepeaterStrategy#isRunning()
	 */
	@Override
	public boolean isRunning() {
		return this.isRunning;
	}

	public SleepRepeaterStrategy(final RepeaterAction repeaterAction) {
		super(repeaterAction);
		this.updateTimeTask = new UpdateTimeTask();

	}

	/**
	 * Android probably never calls this method. So 'we have to' call it.
	 * 
	 * @see ch.quantasy.android.repetitive.service.RepeaterStrategy#finalize()
	 */
	@Override
	public void finalize() {
		this.stopTimedRepetition();
		this.thread = null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * ch.quantasy.android.repetitive.service.RepeaterStrategy#startTimedRepetition
	 * ()
	 */
	@Override
	public void startTimedRepetition() {
		Log.i("Strategy", "++++++++++Sleep");
		if ((this.thread != null) && this.thread.isAlive()) {
			return;
		}
		this.isRunning = true;
		this.thread = new Thread(this.updateTimeTask);
		this.thread.start();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * ch.quantasy.android.repetitive.service.RepeaterStrategy#stopTimedRepetition
	 * ()
	 */
	@Override
	public synchronized void stopTimedRepetition() {
		this.isRunning = false;
		if (this.thread != null) {
			this.thread.interrupt();
		}
		this.setUpdateInterval(0, TimeUnit.SECONDS);
	}

	@Override
	protected void prepareRepetition() {
		if (this.thread != null) {
			Log.d(SleepRepeaterStrategy.TAG, "prepareRepetition: interrupt");
			this.thread.interrupt();
		}

	}

	class UpdateTimeTask implements Runnable {
		@Override
		public void run() {
			try {
				WakeLockManager.s_acquire();
				while (SleepRepeaterStrategy.this.isRunning()) {
					final long updateInterval = SleepRepeaterStrategy.this
							.getUpdateIntervalInMillis();
					if (updateInterval == 0) {
						SleepRepeaterStrategy.this.stopTimedRepetition();
						continue;
					}

					try {
						Log.d(SleepRepeaterStrategy.TAG,
								"" + Math.max(0, updateInterval));
						Thread.sleep(updateInterval, 0);
					} catch (final InterruptedException ex) {
						Log.d(SleepRepeaterStrategy.TAG, "Interrupted");
					}
					if (SleepRepeaterStrategy.this.isRunning()) {
						SleepRepeaterStrategy.this.act();
					}
				}
			} finally {
				WakeLockManager.s_release();
			}
		}

	}

}
